import javax.crypto.Cipher;
import java.io.FileOutputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RSAEncryptionExample {
    public static void main(String[] args) throws Exception {
        // 生成RSA密钥对
        KeyPair keyPair = generateRSAKeyPair();
        // 获取公钥和私钥
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 将公钥转换为字符串
        String publicKeyString = publicKeyToString(keyPair.getPublic());
        System.out.println("Public Key String: " + publicKeyString);

        // 将私钥转换为字符串
        String privateKeyString = privateKeyToString(keyPair.getPrivate());
        System.out.println("Private Key String: " + privateKeyString);

        // 从字符串还原公钥
        publicKey = stringToPublicKey(publicKeyString);
        System.out.println("Recovered Public Key: " + publicKey);

        // 从字符串还原私钥
        privateKey = stringToPrivateKey(privateKeyString);
        System.out.println("Recovered Private Key: " + privateKey);


        // 保存密钥对到文件
//        saveKeyToFile("public.key", publicKey);
//        saveKeyToFile("private.key", privateKey);

        // 要加密的原始数据
        String originalText = "Hello, World!";
        System.out.println("Original Text: " + originalText);

        // 使用公钥加密数据
        byte[] encryptedData = encryptData(originalText, publicKey);

        // 使用私钥解密数据
        String decryptedText = decryptData(encryptedData, privateKey);
        System.out.println("Decrypted Text: " + decryptedText);
    }

    // 生成RSA密钥对
    public static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 设置密钥长度为2048位
        return keyPairGenerator.generateKeyPair();
    }

    // 使用公钥加密数据
    public static byte[] encryptData(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data.getBytes());
    }

    // 使用私钥解密数据
    public static String decryptData(byte[] encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedData);
        return new String(decryptedBytes);
    }

    // 将公钥转换为字符串
    public static String publicKeyToString(PublicKey publicKey) {
        return Base64.getEncoder().encodeToString(publicKey.getEncoded());
    }

    // 将私钥转换为字符串
    public static String privateKeyToString(PrivateKey privateKey) {
        return Base64.getEncoder().encodeToString(privateKey.getEncoded());
    }

    // 从字符串还原公钥
    public static PublicKey stringToPublicKey(String publicKeyString) throws Exception {
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        return keyFactory.generatePublic(keySpec);
    }

    // 从字符串还原私钥
    public static PrivateKey stringToPrivateKey(String privateKeyString) throws Exception {
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyString);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        return keyFactory.generatePrivate(keySpec);
    }


    // 保存密钥到文件
    public static void saveKeyToFile(String fileName, Key key) throws Exception {
        try (FileOutputStream fos = new FileOutputStream(fileName)) {
            fos.write(key.getEncoded());
        }
    }
}
